package org.ponly.uno4j.core.impl;

import org.ponly.common.util.LocalHost;
import org.ponly.uno4j.core.OOoProcess;

import java.util.LinkedHashMap;
import java.util.Map;

import static org.ponly.uno4j.util.UnoUtils.getUniqueKey;

/**
 * 嵌入式 UnoClient 实现
 * <p/>
 * 该类主要实现服务程序和客户端程序在同一台机器
 * <p/>
 * <code>
 * <pre>
 * String unoUrl = "uno:socket,host=localhost,port=8888;";
 * new EmbeddedUnoClientImpl(unoUrl, 8888, 1);
 * </pre>
 * </code>
 */
public class EmbeddedUnoClientImpl extends LbUnoClientImpl {
    private final Map<String, OOoProcess> aliveProcesses = new LinkedHashMap<String, OOoProcess>();

    public EmbeddedUnoClientImpl(String connectType, int sPort, int processCount) {
        this(buildUnoUrls(connectType, sPort, processCount));
    }

    private static String[] buildUnoUrls(String connectType, int sPort, int processCount) {
        int port = sPort;
        String[] unoUrls = new String[processCount];
        for (int i = 0; i < processCount; i++) {
            if ("socket".equals(connectType)) {
                for (; !LocalHost.isAvailablePort(port); port++) ;
                unoUrls[i] = "socket,host=localhost,port=" + (port++) + ",tcpNoDelay=1";
            } else {
                unoUrls[i] = "pipe,name=Pipe-" + i + "-" + getUniqueKey().replace(":", "_");
            }
        }
        return unoUrls;
    }

    public EmbeddedUnoClientImpl(String... unoUrls) {
        super(unoUrls);

        for (String unoUrl : unoUrls) {
            aliveProcesses.put(unoUrl, new OOoProcess(unoUrl));
        }
    }

    public EmbeddedUnoClientImpl start() {
        // 启动服务进程
        synchronized (aliveProcesses) {
            for (OOoProcess process : aliveProcesses.values()) {
                process.start();
            }
        }
        return this;
    }

    @Override
    public void shutdown() {
        // 先关闭其他资源, 再关闭服务进程
        super.shutdown();
        synchronized (aliveProcesses) {
            for (OOoProcess oOoProcess : aliveProcesses.values()) {
                oOoProcess.stop();
            }
        }
    }
}
